package basis.idnr;


/**
 * Diese Klasse dient der Speicherung und Wiedergabe von ISBN13-Nummern.
 * 
 * Datei: ISBN13.java                   
 * Datum: 19.11.2011   
 *                  
 * @author Alexander Bredo 
 * @version 0.3
 */
public class ISBN13 extends Identifikationsnummer
{
  private static final long serialVersionUID = 5833515288605076650L;
  private static final int isbn13prefix = 978;
  protected long isbn;

  
  /**
   * Erstellt ein ISBN13-Objekt aus einer Zeichenfolge
   */
  public ISBN13 (String isbn) throws IllegalArgumentException
  {
    this (gibZahl (isbn));
  }

  
  /**
   * Erstellt ein ISBN13-Objekt aus einer Zahl
   */
  public ISBN13 (long isbn) throws IllegalArgumentException
  {
    if (!istGueltigeLaenge (isbn))
    {
      throw new IllegalArgumentException (
          "Die ISBN hat nicht die richtige Laenge (13 Zeichen).");
    }
    if (!istGueltig (isbn))
    {
      throw new IllegalArgumentException (
          "Die Pruefsumme stimmt nicht mit der ISBN ueberein.");
    }

    this.isbn = isbn;
  }


  /**
   * Prueft die ISBN-Nummer auf Uebereinstimmung mit der Pruefsumme 
   * und auf ihre Laenge
   */
  public boolean istGueltig (long isbn)
  {
    if (!istGueltigeLaenge (isbn))
    {
      return false;
    }

    if (isbn % 10 == gibBerechnetePruefziffer (isbn))
    {
      return true;
    }
    else
    {
      return false;
    }
  }
  
  /**
   * Prueft die ISBN-Zeichenfolge auf Uebereinstimmung mit der Pruefsumme 
   * und auf ihre Laenge
   */
  public boolean istGueltig (String isbn)
  {
    return istGueltig (gibZahl (isbn));
  }
  
  
  /**
   * Gibt die ISBN-Nummer als String zurueck.
   */
  public String toString ()
  {
    return gibZahlMitFuehrenderNull (isbn, gibGueltigeLaenge ());
  }
  
  
  /**
   * Gibt die ISBN-Nummer als long zurueck
   */
  @Override public long toLong ()
  {
    return isbn;
  }
  
  
  /**
   * Gibt die gueltige Laenge einer ISBN13 zurueck.
   */
  protected int gibGueltigeLaenge ()
  {
    return 13;
  }
  
  
  /**
   * Gibt die berechnete Pruefziffer einer ISBN13 zurueck
   */
  protected static int gibBerechnetePruefziffer (long isbn)
  {
    isbn = isbn / 10;                   /* Letzte Stelle ignorieren   */
    long ergebnis = 0;
    
    for (int i = 2; i <= 13; i++)
    {
      long tmp = (long) (isbn % 10);    /* Letzte Stelle merken       */
      if (i % 2 == 0)                   /* gerade Faelle              */
      {
        ergebnis = ergebnis + 3 * tmp;
      }
      else                              /* ungerade Faelle            */
      {
        ergebnis = ergebnis + tmp;
      }
      isbn = isbn / 10;
    }
    return (int) (10 - (ergebnis % 10));/* Differenz zu 10            */
  }
  
  
  /**
   * Konvertiert eine ISBN10 in eine gueltige ISBN13
   */
  public static ISBN13 konvertiereISBN10in13 (ISBN10 isbn10)
  {
    /* ISBN13-Prefix hinzufuegen und Pruefsumme entfernen, berechnen  */
    String tmp = isbn13prefix + isbn10.toString ();   
    tmp = tmp.substring (0, 12) + 
        gibBerechnetePruefziffer (gibZahl (tmp));
    return new ISBN13 (tmp); 
  }
}
